package com.liuzhao.clients.core;

import com.liuzhao.clients.handler.HiHandler;
import com.liuzhao.common.codc.RequestEncoder;
import com.liuzhao.common.codc.ResponseDecoder;
import com.liuzhao.common.model.Request;
import com.liuzhao.common.module.fuben.request.FightRequest;
import org.jboss.netty.bootstrap.ClientBootstrap;
import org.jboss.netty.channel.*;
import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;

import java.net.InetSocketAddress;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * netty客户端入门
 *
 * @author liuxianzhao
 */
public class NettyClientStartup {

    private static String connectIp = "127.0.0.1";
    private static int connectPort = 10101;  //服务端口

    private ExecutorService boss = null;    //boss线程监听端口

    private ExecutorService worker = null;  //worker线程负责数据读写

    private Channel channel = null;

    private ClientBootstrap bootstrap = null;

    public void start() {
        try {
            //服务类
            bootstrap = new ClientBootstrap();

            //线程池
            boss = Executors.newCachedThreadPool();
            worker = Executors.newCachedThreadPool();

            //socket工厂
            bootstrap.setFactory(new NioClientSocketChannelFactory(boss, worker));

            //管道工厂
            bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
                public ChannelPipeline getPipeline() throws Exception {
                    ChannelPipeline pipeline = Channels.pipeline();
                    pipeline.addLast("decoder", new ResponseDecoder());
                    pipeline.addLast("encoder", new RequestEncoder());
                    pipeline.addLast("hiHandler", new HiHandler());
                    return pipeline;
                }
            });

            doBind();
            System.out.println("client start");

            Scanner scanner = new Scanner(System.in);
            while (true) {
                System.out.println("请输入");
                int fubenId = Integer.parseInt(scanner.nextLine());
                int count = Integer.parseInt(scanner.nextLine());

                FightRequest fightRequest = new FightRequest();
                fightRequest.setFubenId(fubenId);
                fightRequest.setCount(count);

                Request request = new Request();
                request.setModule((short) 1);
                request.setCmd((short) 1);
                request.setData(fightRequest.getBytes());
                request.setDataLength(fightRequest.getBytes().length);
                //发送请求
                channel.write(request);
            }
        } finally {
            worker.shutdown();
            boss.shutdown();
        }
    }

    private void doBind() {
        try {
            //连接服务端
            ChannelFuture connect = bootstrap.connect(new InetSocketAddress(connectIp, connectPort));
            channel = connect.sync().getChannel();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    public static void setConnectPort(int connectPort) {
        NettyClientStartup.connectPort = connectPort;
    }

    private static class Singleton {
        private static NettyClientStartup singleton = new NettyClientStartup();
    }

    public static NettyClientStartup newInstance() {
        return Singleton.singleton;
    }
}
